//
// Created by casdon on 2024/8/1.
//

#ifndef CIOT_CSDK_MQTT_H
#define CIOT_CSDK_MQTT_H

#include <ciot/ciot.h>

#ifdef __cplusplus
extern "C" {
#endif

#define MAX_PRODUCT_ID_LEN 64
#define MAX_DEVICE_ID_LEN 64
#define MAX_USER_ID_LEN 64
#define MQTT_PASS_LEN 64

#define CIOT_MQTT_MAX_BUFFER_LEN 2048

typedef enum Ciot_cloud_mqtt_version_e
{
    Ciot_cloud_mqtt_version_3,
    Ciot_cloud_mqtt_version_4,
    Ciot_cloud_mqtt_version_5,
} Ciot_cloud_mqtt_version;

typedef enum Ciot_mqtt_connection_status_e
{
    Ciot_mqtt_connection_status_idle = 0,
    Ciot_mqtt_connection_status_connecting,
    Ciot_mqtt_connection_status_connected,
    Ciot_mqtt_connection_status_disconnected,

    Ciot_mqtt_connection_status_authorization,
    Ciot_mqtt_connection_status_verified,
    Ciot_mqtt_connection_status_author_failed,
    Ciot_mqtt_connection_status_rebind,
    Ciot_mqtt_connection_status_no_access,
    Ciot_mqtt_connection_status_blocked,

    Ciot_mqtt_connection_status_error,

    Ciot_mqtt_connection_status_MAX

} Ciot_mqtt_connection_status;

typedef struct ciot_mqtt_adapter_manager_t
{
    bool inited;
    Ciot_cloud_mqtt_version mqttVersion;

    bool verified;

    CIOT_PRIVATE
    Ciot_res (* msg_received) ( const char * topic, const char * msg );

    CIOT_API
    Ciot_res (* msg_send) ( const char * topic, const char * msg, int len, int qos );

    /**
     *
     * @param topic
     * @param qos
     * @return MessageID of subscription
     */
    CIOT_ADAPTER
    int (* subscribe) ( const char * topic, int qos );

    CIOT_ADAPTER
    Ciot_res (* unsubscribe) ( const char * topic );

    // If use msgID, set topicID to Ciot_cloud_topic_MAX
    // If use topicID, set msgID to Ciot_OK
    CIOT_EVENT
    Ciot_res (* subscribed) (int msgID, Ciot_cloud_topic topicID);

    CIOT_EVENT
    Ciot_res (* unsubscribed) (int msgID, Ciot_cloud_topic topicID);

    CIOT_API
    Ciot_res (* connect_server) ( const char * host, int port, const char * pid, const char * did, const char * mqtt_password );

    CIOT_EVENT
    Ciot_res (* connected) ();

    CIOT_API
    Ciot_res (* disconnect_server) (void);

    CIOT_EVENT
    Ciot_res (* disconnected) ();

} ciot_mqtt_adapter_manager;

extern Ciot_res ciot_porting_mqtt_init();

CIOT_API
Ciot_res ciot_mqtt_adapter_manager_reg( ciot_mqtt_adapter_manager * mqtt_adapter );

CIOT_API
const ciot_mqtt_adapter_manager * ciot_mqtt_adapter_manager_instance();

#define ciot_mqtt_mgr() ciot_mqtt_adapter_manager_instance()
#define ciot_mqtt() ciot_mqtt_mgr()

const char * ciot_cloud_get_topic_str( Ciot_cloud_topic topic );

Ciot_res ciot_cloud_check_topic( const char * topicStr );

Ciot_cloud_topic ciot_cloud_get_topic( const char * topicStr );

const char * ciot_mqtt_adapter_get_topic_str( Ciot_cloud_topic topic );

Ciot_res ciot_mqtt_adapter_check_topic( const char * topicStr );

Ciot_cloud_topic ciot_mqtt_adapter_get_topic( const char * topicStr );

#ifdef __cplusplus
}
#endif

#endif //CIOT_CSDK_MQTT_H
